package com.java.simple.smallspring.core.convert.converter;

import cn.hutool.core.lang.Assert;
import lombok.Getter;

import java.util.Objects;
import java.util.Set;

/**
 * @author zhoujunlin
 * @date 2022年11月19日 13:17
 * @desc 通用的转换接口
 */
public interface GenericConverter {

    /**
     * holder for a source-to-target class pare
     * 内部类可交换类型对
     */
    @Getter
    final class ConvertiblePair {
        private final Class<?> sourceType;
        private final Class<?> targetType;

        public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {
            Assert.notNull(sourceType, "Source type must not be null");
            Assert.notNull(targetType, "Target type must not be null");
            this.sourceType = sourceType;
            this.targetType = targetType;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            ConvertiblePair that = (ConvertiblePair) o;
            return Objects.equals(sourceType, that.sourceType) && Objects.equals(targetType, that.targetType);
        }

        @Override
        public int hashCode() {
            return Objects.hash(sourceType, targetType);
        }
    }

    /**
     * return the source and target types that this convert can convert between
     *
     * @return
     */
    Set<ConvertiblePair> getConvertibleTypes();

    /**
     * convert the source object to the targetType
     *
     * @param source
     * @param sourceType
     * @param targetType
     * @return the converted object
     */
    Object convert(Object source, Class sourceType, Class targetType);

}
